package com.mnsq.common.service;

import com.alibaba.fastjson.JSONObject;
import com.mnsq.common.bean.enums.TimeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @author Administrator
 * @date 2019/3/21 0021
 */
@Component
public class RedisServer<K, V> {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public void setValue(K k, V v, Long timeOutSeconds) {
        redisTemplate.opsForValue().set(getKey(k), JSONObject.toJSONString(v), timeOutSeconds, TimeUnit.SECONDS);
    }

    public void setValue(K k, V v) {
        this.setValue(k, v, TimeEnum.HOUR_TWENTY_FOUR.time);
    }

    public String get(K k) {
        return redisTemplate.opsForValue().get(getKey(k));
    }

    public V get(K k, Class<V> v) {
        return JSONObject.parseObject(redisTemplate.opsForValue().get(getKey(k)), v);
    }

    public void del(K k) {
        redisTemplate.delete(getKey(k));
    }

    public void renew(K k, Long times) {
        redisTemplate.expire(getKey(k), times, TimeUnit.SECONDS);
    }

    public boolean hasKey(K k) {
        return redisTemplate.hasKey(getKey(k));
    }

    private String getKey(K k) {
        if (k instanceof String
                || k instanceof Long
                || k instanceof Character
                || k instanceof Boolean
                || k instanceof Double
                || k instanceof Float
                ) {
            return k.toString();
        }
        return JSONObject.toJSONString(k);
    }

    /**
     * 原子操作自增
     *
     * @param k
     */
    public void incr(K k) {
        redisTemplate.execute(new RedisCallback<Long>() {
            @Nullable
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                return connection.incr(k.toString().getBytes());
            }
        });
    }
}
